/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package data_generator;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author changliu
 */
public class DataGenerator {

    BufferedReader rdr = null;
    BufferedWriter wrtr = null;
    List<JobInfo> inputJobs;
    List<JobInfo> simulatedJobs;

    public DataGenerator(String input, String output) throws FileNotFoundException, IOException {
        this.rdr = new BufferedReader(new FileReader(input));
        this.wrtr = new BufferedWriter(new FileWriter(output));
        this.inputJobs = new ArrayList<>();
        this.simulatedJobs = new ArrayList<>();
    }

    private void cleanup() {
        try {
            this.rdr.close();
            this.wrtr.close();
        } catch (Exception ex) {
        }
    }

    public boolean generate() throws IOException {
        if (false == this.loadData()) {
            System.out.println("error when loading data.");
            return false;
        }
        if (false == this.simulate()) {
            System.out.println("error when generating data.");
            return false;
        }
        if (false == this.writeData()) {
            System.out.println("error when writing data.");
            return false;
        }
        this.cleanup();
        return true;
    }

    private boolean loadData() {
        try {
            String line = this.rdr.readLine();
            String[] tokens;

            while (line != null) {
                JobInfo job = new JobInfo();
                tokens = line.split(" ");
                int taskCnt = Integer.parseInt(tokens[0]);
                job.cnt = Integer.parseInt(tokens[2]);
                job.prob = Float.parseFloat(tokens[1]);
                for (int i = 0; i < taskCnt; i++) {
                    line = this.rdr.readLine();
                    job.tasks.add(line);
                }
                this.inputJobs.add(job);
                line = this.rdr.readLine();
            }
            return true;
        } catch (IOException ex) {
            return false;
        }

    }

    private boolean simulate() {
        for (JobInfo job : this.inputJobs) {
            // how many time to simulate
            for (int i = 0; i < job.cnt; i++) {
                JobInfo simulatedJob = new JobInfo();
                simulatedJob.tasks.add(job.tasks.get(0));
                // start from 1, because the first task always happens
                for (int j = 1; j < job.tasks.size(); j++) {
                    if (this.happen(job.prob)) {
                        simulatedJob.tasks.add(job.tasks.get(j));
                    } else {
                        break;
                    }
                }
                this.simulatedJobs.add(simulatedJob);
            }
        }
        return true;
    }

    private boolean happen(float prob) {
        int min = 1;
        int max = 100;
        int rdm = min + (int) (Math.random() * ((max - min) + 1));
        if (rdm > prob * 100) {
            return false;
        }
        return true;
    }

    private boolean writeData() {
        try {
            for (JobInfo job : this.simulatedJobs) {
                for (int j = 0; j < job.tasks.size(); j++) {
                    this.wrtr.write(job.tasks.get(j) + "\n");
                }
                this.wrtr.write("\n");
            }
        } catch (IOException ex) {
            return false;
        }
        return true;
    }
}
